﻿using MetaVideoEditorEvolved.Helper;
/*
 * Created by SharpDevelop.
 * User: Masy Freddy
 * Date: 12/10/2011
 * Time: 5:33
 */
namespace mveEngine
{
	using System;
	using System.Collections;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.Diagnostics;
	using System.Globalization;
	using System.IO;
	using System.Linq;
	using System.Net;
	using System.Runtime.InteropServices;
	using System.Security.Cryptography;
	using System.Text;
	using System.Text.RegularExpressions;
	using System.Web;
	using System.Xml;

	using MetaVideoEditorEvolved.Engine;
	using MetaVideoEditorEvolved.Engine.Entity;
	using mveEngine.Comparer;

	public class ProvidersUtil
	{
		public static void LocalFetch(Item item)
		{
			try
			{
				switch (item.Type) {
					case Entity.Movie:
					case Entity.Folder:
						var movie = AddInReaderManager.Current.ReadMovie(item.Path);
						
						if(movie != null)
						{
							item.ImagesPaths = new ObservableCollection<Poster>((from p in movie.Posters
							                                                     select new Poster
							                                                     {
							                                                     	Image = p.LocalPath
							                                                     }).ToList());
							
							if(item.ImagesPaths.Any())
							{
								item.PrimaryImage = item.ImagesPaths.First();
								item.PrimaryImage.Checked = true;
							}
							
							item.BackdropImagePaths = new ObservableCollection<Poster>((from p in movie.Backdrops
							                                                            select new Poster
							                                                            {
							                                                            	Image = p.LocalPath
							                                                            }).ToList());
							
							if(item.BackdropImagePaths.Any())
							{
								item.PrimaryBackdrop = item.BackdropImagePaths.First();
								item.PrimaryBackdrop.Checked = true;
							}
							
							item.Actors = new ObservableCollection<Actor>((from a in movie.CastMembers
							                                               where a.Activity.ToLower().Contains("act")
							                                               select new Actor
							                                               {
							                                               	ImagePath = a.Picture == null ? null : a.Picture.LocalPath,
							                                               	Name = a.FullName,
							                                               	Role = a.Role
							                                               }).ToList());
							
							item.Crew = new List<CrewMember>((from a in movie.CastMembers
							                                  where !a.Activity.ToLower().Contains("act")
							                                  select new CrewMember
							                                  {
							                                  	Name = a.FullName,
							                                  	Activity = a.Activity
							                                  }).ToList());
							
							item.TrailerFiles = new ObservableCollection<string>((from t in movie.Trailers
							                                                      select t.DefaultPath.LocalPath).ToList());
							
							item.Genres = movie.Genres != null ? new List<string>(movie.Genres) : new List<string>();
							item.Studios = movie.Studios != null ? new List<string>(movie.Studios) : new List<string>();
							item.Countries = movie.Nationalities != null ? new List<string>(movie.Nationalities) : new List<string>();
							item.Title = movie.Title;
							item.Year = movie.Year;
							item.RunningTime = movie.Duration;
							item.OriginalTitle = movie.OriginalTitle;
							item.Overview = movie.Overview;
							item.Rating = movie.Rating;
							item.IsInError = movie.IsInError;
						}
						break;
					case Entity.Series:
						var serie = AddInReaderManager.Current.ReadSerie(item.Path);
						
						if(serie != null)
						{
							item.BackdropImagePaths = new Collection<Poster>((from b in serie.Backdrops
							                                                  select new Poster
							                                                  {
							                                                  	Image = b.LocalPath
							                                                  }).ToList());
							
							if(item.BackdropImagePaths.Any())
							{
								item.PrimaryBackdrop = item.BackdropImagePaths.First();
								item.PrimaryBackdrop.Checked = true;
							}
							
							item.ImagesPaths = new ObservableCollection<Poster>((from b in serie.Posters
							                                                     select new Poster
							                                                     {
							                                                     	Image = b.LocalPath
							                                                     }).ToList());
							
							if(item.ImagesPaths.Any())
							{
								item.PrimaryImage = item.ImagesPaths.First();
								item.PrimaryImage.Checked = true;
							}
							
							item.BannersPaths = new List<Poster>((from b in serie.Graphicals
							                                      select new Poster
							                                      {
							                                      	Image = b.LocalPath
							                                      }).ToList());
							
							if(item.BannersPaths.Any())
							{
								item.PrimaryBanner = item.BannersPaths.First();
								item.PrimaryBanner.Checked = true;
							}
							
							item.Actors = new ObservableCollection<Actor>((from a in serie.CastMembers
							                                               where a.Activity.ToLower().Contains("act")
							                                               select new Actor
							                                               {
							                                               	ImagePath = a.Picture == null ? null : a.Picture.LocalPath,
							                                               	Name = a.FullName,
							                                               	Role = a.Role
							                                               }).ToList());
							
							item.Crew = new List<CrewMember>((from a in serie.CastMembers
							                                  where !a.Activity.ToLower().Contains("act")
							                                  select new CrewMember
							                                  {
							                                  	Name = a.FullName,
							                                  	Activity = a.Activity
							                                  }).ToList());
							
							item.RunningTime = serie.Duration;
							item.Genres = serie.Genres != null ? new List<string>(serie.Genres) : new List<string>();
							item.Title = serie.Name;
							item.Overview = serie.Overview;
							item.Rating = serie.Rating;
							item.Studios = serie.Studios != null ? new List<string>( serie.Studios) : new List<string>();
							item.Year = serie.Year;
							item.PrimaryProviderSerieId = serie.Id;
							item.IsInError = serie.IsInError;
						}
						break;
					case Entity.Season:
						var season = AddInReaderManager.Current.ReadSeason(item.Path);
						
						if(season != null)
						{
							item.ImagesPaths = new ObservableCollection<Poster>((from p in season.Images
							                                                     select new Poster
							                                                     {
							                                                     	Image = p.LocalPath
							                                                     }).ToList());
							
							if(item.ImagesPaths.Any())
							{
								item.PrimaryImage = item.ImagesPaths.First();
								item.PrimaryImage.Checked = true;
							}
							
							item.IsInError = season.IsInError;
						}
						break;
					case Entity.Episode:
						var episode = AddInReaderManager.Current.ReadEpisode(item.Path);
						
						if(episode != null)
						{
							item.Title = episode.Name ;
							item.EpisodeNumber = episode.Number.ToString();
							item.Overview = episode.Overview;
							item.Rating = episode.Rating;
							item.SeasonNumber = episode.SeasonNumber.ToString();
							item.Year = episode.Year;
							item.FirstAired = episode.FirstAired;
							item.Crew = new List<CrewMember>();
							foreach (var element in episode.Directors) {
								item.Crew.Add(new CrewMember
								              {
								              	Activity = "Director",
								              	Name = element
								              });
							}
							
							foreach (var element in episode.Writers) {
								item.Crew.Add(new CrewMember
								              {
								              	Activity = "Writer",
								              	Name = element
								              });
							}
							
							item.Actors = new ObservableCollection<Actor>();
							
							foreach (var element in episode.GuestStars) {
								item.Actors.Add(new Actor
								                {
								                	Name = element,
								                	Role = "Actor"
								                });
							}
							
							item.ImagesPaths =new ObservableCollection<Poster>((from p in episode.Images
							                                                    select new Poster
							                                                    {
							                                                    	Image = p.LocalPath
							                                                    }).ToList());
							if(item.ImagesPaths.Any())
							{
								item.PrimaryImage = item.ImagesPaths.First();
								item.PrimaryImage.Checked = true;
							}
							
							item.IsInError = episode.IsInError;
						}
						break;
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError("Exception in LocalFetch from providerutil in " + item.Path, ex);
				throw;
			}
		}
		
		public static Item AutoFind(Item item)
		{
			try
			{
				Collection<ProviderSearchMedia> searchMedias = null;
				List<Item> items = new List<Item>();
				switch(item.Type)
				{
					case Entity.Movie:
					case Entity.Folder:
						searchMedias = AddInProviderManager.Current.AutoFind(MediaType.Movie, item.Title);
						
						foreach (var media in searchMedias) {
							Item itemmedia = new Item();
							
							itemmedia.Type = mveEngine.Entity.Movie;
							itemmedia.Id = media.Id.ToString();
							itemmedia.ProvidersId = new List<DataProviderId>
							{
								new DataProviderId()
								{
									Id = media.ProviderId.ToString(),
									Name = media.ProviderName,
									Url = media.MediaUrl.AbsoluteUri
								}
							};
							
							items.Add(itemmedia);
						}
						break;
						
					case Entity.Series:
						searchMedias = AddInProviderManager.Current.AutoFind(MediaType.Serie, item.Title);
						
						foreach (var media in searchMedias) {
							Item itemmedia = new Item();
							
							itemmedia.Type = mveEngine.Entity.Series;
							itemmedia.PrimaryProviderSerieId = media.Id.ToString();
							itemmedia.Id = media.Id.ToString();
							itemmedia.ProvidersId = new List<DataProviderId>
							{
								new DataProviderId()
								{
									Id = media.ProviderId.ToString(),
									Name = media.ProviderName,
									Url = media.MediaUrl == null ? null : media.MediaUrl.AbsoluteUri
								}
							};
							
							items.Add(itemmedia);
						}
						break;
					case Entity.Season:
						var season = AddInProviderManager.Current.FetchSeason(item.PrimaryProviderSerieId, int.Parse(item.SeasonNumber), Guid.Empty);
						
						if(season!=null)
						{
							if(season.Images.Any())
							{
								item.ImagesPaths = new ObservableCollection<Poster>((from p in season.Images
								                                                     select new Poster
								                                                     {
								                                                     	Image = p.AbsoluteUri
								                                                     }).ToList());
								
								item.PrimaryImage = item.ImagesPaths.First();
							}
						}
						
						return item;
					case Entity.Episode:
						var episode = AddInProviderManager.Current.FetchEpisode(item.PrimaryProviderSerieId, int.Parse(item.SeasonNumber), int.Parse(item.EpisodeNumber), Guid.Empty);
						
						if(episode!=null)
						{
							item.Year = episode.Year;
							item.SeasonNumber = episode.SeasonNumber.ToString();
							item.Rating = episode.Rating;
							item.Overview = episode.Overview;
							item.EpisodeNumber = episode.Number.ToString();
							item.Title = episode.Name;
							item.FirstAired = episode.FirstAired;
							
							item.Actors = new ObservableCollection<Actor>();
							
							foreach (var element in episode.GuestStars) {
								item.Actors.Add(new Actor
								                {
								                	Name = element
								                });
							}
							
							item.Crew = new List<CrewMember>();
							
							foreach (var element in episode.Directors) {
								item.Crew.Add(new CrewMember
								              {
								              	Name = element,
								              	Activity = "Director"
								              });
							}
							
							foreach (var element in episode.Writers) {
								item.Crew.Add(new CrewMember
								              {
								              	Name = element,
								              	Activity = "Writer"
								              });
							}
							
							if(episode.Images.Any())
							{
								item.ImagesPaths = new ObservableCollection<Poster>((from p in episode.Images
								                                                     select new Poster
								                                                     {
								                                                     	Image = p.AbsoluteUri
								                                                     }).ToList());
								
								item.PrimaryImage = item.ImagesPaths.First();
							}
						}
						
						return item;
				}
				
				if(items.Any())
				{
					return MultiFetch(items);
				}
				else
				{
					return null;
				}
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError("Exception in AutoFind from ProviderUtil in " + item.Title, ex);
				throw;
			}
		}

		public static List<Item> FindPossible(Item item)
		{
			try
			{
				List<Item> items = new List<Item>();
				
				if(item.Type == Entity.Movie || item.Type == Entity.Folder)
				{
					var resultMovie = AddInProviderManager.Current.FindPossible(MediaType.Movie, item.Title);
					
					foreach (var movie in resultMovie) {
						items.Add(new Item
						          {
						          	Id = movie.Id.ToString(),
						          	Title = movie.Name,
						          	ProvidersId = new List<DataProviderId>()
						          	{
						          		new DataProviderId
						          		{
						          			Id= movie.ProviderId.ToString(),
						          			Url = movie.MediaUrl == null ? null : movie.MediaUrl.AbsoluteUri,
						          			Name=movie.ProviderName
						          		}
						          	},
						          	PrimaryImage = movie.Picture == null ? null : new Poster
						          	{
						          		Image = movie.Picture.AbsoluteUri
						          	},
						          	OriginalTitle = movie.OriginalName,
						          	Overview = movie.Overview,
						          	Year = movie.Year,
						          	Type = item.Type,
						          	Rating = item.Rating.HasValue ? item.Rating.Value : 0.0F
						          });
					}
				}
				else
				{
					if(item.Type == Entity.Series)
					{
						var resultSerie = AddInProviderManager.Current.FindPossible(MediaType.Serie, item.Title);
						
						foreach (var serie in resultSerie) {
							items.Add(new Item
							          {
							          	Id = serie.Id.ToString(),
							          	Title = serie.Name,
							          	ProvidersId = new List<DataProviderId>()
							          	{
							          		new DataProviderId
							          		{
							          			Id = serie.ProviderId.ToString(),
							          			Url = serie.MediaUrl == null ? null : serie.MediaUrl.AbsoluteUri,
							          			Name=serie.ProviderName
							          		}
							          	},
							          	PrimaryImage = serie.Picture == null ? null : new Poster
							          	{
							          		Image = serie.Picture.AbsoluteUri
							          	},
							          	OriginalTitle = serie.OriginalName,
							          	Overview = serie.Overview,
							          	Year = serie.Year,
							          	Type = item.Type
							          });
						}
					}
				}
				
				return items;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError("Exception in FindPossible from providerUtil in " + item.Title, ex);
				throw;
			}
		}

		public static Item Fetch(Item item)
		{
			try
			{
				Item internalItem = null;
				
				switch(item.Type)
				{
					case Entity.Movie:
					case Entity.Folder:
						var movie = AddInProviderManager.Current.FetchMovie(int.Parse(item.Id), new Guid(item.ProvidersId.First().Id));
						
						internalItem = new Item();
						internalItem.Actors = new ObservableCollection<Actor>((from actor in movie.CastMembers
						                                                       where actor.Activity.ToLower().Contains("act")
						                                                       select new Actor
						                                                       {
						                                                       	Name = actor.FullName,
						                                                       	Role = actor.Role,
						                                                       	ImagePath = actor.Picture == null ? string.Empty : actor.Picture.AbsoluteUri
						                                                       }).ToList());
						
						internalItem.BackdropImagePaths = new Collection<Poster>((from backdrop in movie.Backdrops
						                                                          select new Poster
						                                                          {
						                                                          	Image = backdrop.AbsoluteUri
						                                                          }).ToList());
						
						if(internalItem.BackdropImagePaths.Any())
						{
							internalItem.PrimaryBackdrop = internalItem.BackdropImagePaths.First();
						}
						
						internalItem.Countries = new List<string>(movie.Nationalities);
						internalItem.Crew= (from actor in movie.CastMembers
						                    where !actor.Activity.ToLower().Contains("act")
						                    select new CrewMember
						                    {
						                    	Name = actor.FullName,
						                    	Activity = actor.Activity
						                    }).ToList();
						internalItem.Genres = new List<string>(movie.Genres);
						internalItem.ImagesPaths = new ObservableCollection<Poster>((from poster in movie.Posters
						                                                             select new Poster
						                                                             {
						                                                             	Image = poster.AbsoluteUri
						                                                             }).ToList());
						
						if(internalItem.ImagesPaths.Any())
						{
							internalItem.PrimaryImage = internalItem.ImagesPaths.First();
						}
						
						internalItem.OriginalTitle = movie.OriginalTitle;
						internalItem.Overview = movie.Overview;
						internalItem.Rating = float.Parse(movie.Rating.ToString());
						internalItem.RunningTime = movie.Duration;
						internalItem.Studios = new List<string>(movie.Studios);
						internalItem.Title= movie.Title;
						internalItem.TrailerFiles = new System.Collections.ObjectModel.ObservableCollection<string>((from t in movie.Trailers
						                                                                                             select t.DefaultPath.AbsoluteUri).ToList());
						internalItem.Type = Entity.Movie;
						internalItem.Year = movie.Year;
						break;
					case Entity.Series:
						var serie = AddInProviderManager.Current.FetchSerie(item.Id, new Guid(item.ProvidersId.First().Id));
						
						internalItem = new Item();
						
						internalItem.BackdropImagePaths = new ObservableCollection<Poster>((from poster in serie.Backdrops
						                                                                    select new Poster
						                                                                    {
						                                                                    	Image = poster.AbsoluteUri
						                                                                    }).ToList());
						
						if(internalItem.BackdropImagePaths.Any())
						{
							internalItem.PrimaryBackdrop = internalItem.BackdropImagePaths.First();
						}
						
						internalItem.ImagesPaths = new ObservableCollection<Poster>((from poster in serie.Posters
						                                                             select new Poster
						                                                             {
						                                                             	Image = poster.AbsoluteUri
						                                                             }).ToList());
						
						if(internalItem.ImagesPaths.Any())
						{
							internalItem.PrimaryImage = internalItem.ImagesPaths.First();
						}
						
						internalItem.BannersPaths = new List<Poster>((from poster in serie.Graphicals
						                                              select new Poster
						                                              {
						                                              	Image = poster.AbsoluteUri
						                                              }).ToList());
						
						if(internalItem.BannersPaths.Any())
						{
							internalItem.PrimaryBanner = internalItem.BannersPaths.First();
						}
						
						internalItem.Actors = new ObservableCollection<Actor>((from actor in serie.CastMembers
						                                                       where actor.Activity.ToLower().Contains("act")
						                                                       select new Actor
						                                                       {
						                                                       	Name = actor.FullName,
						                                                       	Role = actor.Role,
						                                                       	ImagePath = actor.Picture == null ? string.Empty : actor.Picture.AbsoluteUri
						                                                       }).ToList());
						
						internalItem.Genres = new List<string>(serie.Genres);
						internalItem.Title = serie.Name;
						internalItem.Overview =	serie.Overview;
						internalItem.Rating =float.Parse(serie.Rating.ToString());
						internalItem.Studios = new List<string>(serie.Studios);
						internalItem.Year = serie.Year;
						internalItem.PrimaryProviderSerieId = serie.Id.ToString();
						internalItem.Type = Entity.Series;
						break;
					case Entity.Season:
						var season = AddInProviderManager.Current.FetchSeason(item.Id,int.Parse(item.SeasonNumber), new Guid(item.ProvidersId.First().Id));

						if(season != null)
						{
							internalItem.Id = item.Id.ToString();
							internalItem.SeasonNumber = season.Number.ToString();
							internalItem.ImagesPaths = new ObservableCollection<Poster>((from poster in season.Images
							                                                             select new Poster
							                                                             {
							                                                             	Image = poster.AbsoluteUri
							                                                             }).ToList());
							internalItem.Type = Entity.Season;
						}
						break;
					case Entity.Episode:
						var episode = AddInProviderManager.Current.FetchEpisode(item.Id,int.Parse( item.SeasonNumber), int.Parse(item.EpisodeNumber), new Guid(item.ProvidersId.First().Id));

						if(episode != null)
						{
							internalItem.Id = item.Id.ToString();
							internalItem.SeasonNumber = item.SeasonNumber.ToString();
							internalItem.EpisodeNumber = episode.Number.ToString();
							internalItem.Title = episode.Name;
							internalItem.FirstAired = episode.FirstAired;
							
							internalItem.BackdropImagePaths = new Collection<Poster>((from poster in episode.Images
							                                                          select new Poster
							                                                          {
							                                                          	Image = poster.AbsoluteUri
							                                                          }).ToList());
							internalItem.Overview = episode.Overview;
							internalItem.Rating = float.Parse(episode.Rating.ToString());
							internalItem.Year = episode.Year;
							internalItem.Type = Entity.Episode;
						}

						break;
				}
				
				return internalItem;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError("Exception in Fetch from providerutil in " + item.Path, ex);
				throw;
			}
		}

		public static Item MultiFetch(List<Item> items)
		{
			Item item = new Item();
			item.ImagesPaths = new ObservableCollection<Poster>();
			item.BackdropImagePaths = new Collection<Poster>();
			item.BannersPaths = new List<Poster>();
			item.Actors = new ObservableCollection<Actor>();
			item.Crew = new List<CrewMember>();
			item.Genres = new List<string>();
			item.Studios = new List<string>();
			item.Countries = new List<string>();
			
			for (int i = AddInProviderManager.Current.AddIns.Count - 1; i >= 0 ; i--) {
				foreach (var element in items) {
					try
					{
					if(element.ProvidersId[0].Id == AddInProviderManager.Current.AddIns[i].AssemblyId.ToString())
					{
						var fetchItem = Fetch(element);
						
						if(fetchItem != null)
						{
							fetchItem.ProvidersId = element.ProvidersId;
							item.PrimaryProviderSerieId = element.PrimaryProviderSerieId;
							
							foreach (var retrieveProperty in AddInProviderManager.Current.AddIns[i].RetrieveProperty) {
								switch (retrieveProperty) {
									case AddInProperty.Title:
										if(!string.IsNullOrEmpty(fetchItem.Title))
										{
											item.Title = fetchItem.Title;
										}
										break;
									case AddInProperty.OriginalTitle:
										if(!string.IsNullOrEmpty(fetchItem.OriginalTitle))
										{
											item.OriginalTitle = fetchItem.OriginalTitle;
										}
										break;
									case AddInProperty.Poster:
										foreach (var image in fetchItem.ImagesPaths) {
											item.ImagesPaths.Add(image);
										}
										
										item.ImagesPaths = new ObservableCollection<Poster>(item.ImagesPaths.Distinct(new PosterComparer()).ToList());
										
										if(fetchItem.PrimaryImage != null)
										{
											item.PrimaryImage = fetchItem.PrimaryImage;
										}
										break;
									case AddInProperty.Backdrop:
										foreach (var image in fetchItem.BackdropImagePaths) {
											item.BackdropImagePaths.Add(image);
										}

										item.BackdropImagePaths = new Collection<Poster>(item.BackdropImagePaths.Distinct(new PosterComparer()).ToList());
										
										if(fetchItem.PrimaryBackdrop != null)
										{
											item.PrimaryBackdrop = fetchItem.PrimaryBackdrop;
										}
										break;
									case AddInProperty.Banner:
										if(fetchItem.BannersPaths != null)
										{
											item.BannersPaths.AddRange(fetchItem.BannersPaths);
											item.BannersPaths = item.BannersPaths.Distinct(new PosterComparer()).ToList();
										}
										
										if(fetchItem.PrimaryBanner != null)
										{
											item.PrimaryBanner = fetchItem.PrimaryBanner;
										}
										break;
									case AddInProperty.Trailer:
										foreach (var t in fetchItem.TrailerFiles) {
											item.TrailerFiles.Add(t);
										}
										break;
									case AddInProperty.Year:
										if(fetchItem.Year != null || fetchItem.Year.Value != 0)
										{
											item.Year = fetchItem.Year;
										}
										break;
									case AddInProperty.Duration:
										if(fetchItem.RunningTime.HasValue == true && fetchItem.RunningTime.Value != 0)
										{
											item.RunningTime = fetchItem.RunningTime;
										}
										break;
									case AddInProperty.Rating:
										if(fetchItem.Rating.HasValue == true && fetchItem.Rating.Value != 0.0)
										{
											item.Rating = fetchItem.Rating;
										}
										break;
									case AddInProperty.Overview:
										if(!string.IsNullOrEmpty(fetchItem.Overview))
										{
											item.Overview = fetchItem.Overview;
										}
										break;
									case AddInProperty.Casting:
										if(fetchItem.Actors != null)
										{
											foreach (var a in fetchItem.Actors) {
												item.Actors.Add(a);
											}
											item.Actors = new ObservableCollection<Actor>(item.Actors.Distinct(new ActorComparer()));
										}
										
										if(fetchItem.Crew != null)
										{
											foreach (var a in fetchItem.Crew) {
												item.Crew.Add(a);
											}
											
											item.Crew = new List<CrewMember>(item.Crew.Distinct(new CrewComparer()));
										}
										break;
									case AddInProperty.Genre:
										if(fetchItem.Genres != null)
										{
											item.Genres.AddRange(fetchItem.Genres);
											item.Genres = new List<string>(item.Genres.Distinct());
										}
										break;
									case AddInProperty.Studio:
										if(fetchItem.Studios != null)
										{
											item.Studios.AddRange(fetchItem.Studios);
											item.Studios = new List<string>(item.Studios.Distinct());
										}
										break;
									case AddInProperty.Country:
										if(fetchItem.Countries != null)
										{
											item.Countries.AddRange(fetchItem.Countries);
											item.Countries = new List<string>(item.Countries.Distinct());
										}
										break;
									case AddInProperty.MPAARating:
										if(!string.IsNullOrEmpty(fetchItem.MPAARating))
										{
											item.MPAARating = fetchItem.MPAARating;
										}
										break;
								}
							}
						}
					}
					}
					catch(Exception ex)
					{
						Tracer.TracerInstance.TraceError("Exception in MultiFetch from ProviderUtil " + element.Title, ex);
						throw;
					}
				}
			}
			
			if(item.ImagesPaths.Any())
			{
				item.PrimaryImage = item.ImagesPaths.First();
			}
			
			if(item.BackdropImagePaths.Any())
			{
				item.PrimaryBackdrop = item.BackdropImagePaths.First();
			}
			
			if(item.BannersPaths.Any())
			{
				item.PrimaryBanner = item.BannersPaths.First();
			}
			
			return item;
		}

		public static bool Write(Item item)
		{
			try
			{
				if(Config.Instance.UseGenreMapping &&
				   item.Genres!=null)
				{					
					item.Genres = (from genre in item.Genres
					               select GenresMappingManager.MapGenre(genre, item.Type.ToString())).ToList();
				}
				
				switch (item.Type) {
					case Entity.Movie:
					case Entity.Folder:
						Movie movie = new Movie()
						{
							Duration = item.RunningTime.HasValue ? item.RunningTime.Value : 0,
							OriginalTitle = item.OriginalTitle,
							Overview = item.Overview,
							Rating = item.Rating.HasValue ? item.Rating.Value : 0,
							Title = item.Title,
							Year = item.Year.HasValue ? item.Year.Value : 0,
							Backdrops = new Collection<Uri>((from b in item.BackdropImagePaths
							                                 where b.Checked == true && b.Image != item.PrimaryBackdrop.Image
							                                 select new Uri(ImageUtil.GetLocalImagePath(b.Image))).ToList()),
							Posters = new Collection<Uri>((from b in item.ImagesPaths
							                               where b.Checked == true && b.Image != item.PrimaryImage.Image
							                               select new Uri(ImageUtil.GetLocalImagePath(b.Image))).ToList()),
							CastMembers = new Collection<CastMember>(),
							Genres = item.Genres != null ? new Collection<string>(item.Genres) : new Collection<string>(),
							Nationalities = item.Countries != null ? new Collection<string>(item.Countries) : new Collection<string>(),
							Studios = item.Countries != null ? new Collection<string>(item.Studios) : new Collection<string>(),
							Trailers = new Collection<Trailer>((from t in item.TrailerFiles
							                                    where !t.Contains("http")
							                                    select new Trailer()
							                                    {
							                                    	DefaultPath = new Uri(t)
							                                    }).ToList()),
							FullPath = (item.VideoFiles != null && item.VideoFiles.Any()) ? item.VideoFiles.First() : string.Empty
						};
						
						if(item.PrimaryBackdrop != null &&
						   !string.IsNullOrEmpty(item.PrimaryBackdrop.Image))
						{
							movie.Backdrops.Insert(0, new Uri(ImageUtil.GetLocalImagePath(item.PrimaryBackdrop.Image)));
						}
						
						if(item.PrimaryImage != null &&
						   !string.IsNullOrEmpty(item.PrimaryImage.Image))
						{
							movie.Posters.Insert(0, new Uri(ImageUtil.GetLocalImagePath(item.PrimaryImage.Image)));
						}
						
						if(item.Actors != null)
						{
							foreach (var actor in item.Actors) {
								movie.CastMembers.Add(new CastMember
								                      {
								                      	FullName = actor.Name,
								                      	Role = actor.Role,
								                      	Picture = string.IsNullOrEmpty(actor.ImagePath) ? null : new Uri(ImageUtil.GetLocalImagePath(actor.ImagePath)),
								                      	Activity = "Actor"
								                      });
							}
						}
						
						if(item.Crew != null)
						{
							foreach (var crew in item.Crew) {
								movie.CastMembers.Add(new CastMember
								                      {
								                      	FullName = crew.Name,
								                      	Activity = crew.Activity
								                      });
							}
						}
						
						AddInSaverManager.Current.SaveMovie(item.Path, movie);
						break;
					case Entity.Series:
						var serie = new Serie()
						{
							Backdrops = new Collection<Uri>(),
							Posters = new Collection<Uri>(),
							Graphicals = new Collection<Uri>(),
							CastMembers = new Collection<CastMember>(),
							Id = item.PrimaryProviderSerieId,
							Name = item.Title,
							Genres = item.Genres != null ? new Collection<string>(item.Genres) : new Collection<string>(),
							Studios = item.Studios != null ? new Collection<string>(item.Studios) : new Collection<string>(),
							Duration = item.RunningTime.HasValue ? item.RunningTime.Value : 0,
							Overview = item.Overview,
							Rating = item.Rating.HasValue ? item.Rating.Value : 0,
							Year = item.Year.HasValue ? item.Year.Value : 0
						};
						
						if(item.BackdropImagePaths != null)
						{
							serie.Backdrops = new Collection<Uri>((from b in item.BackdropImagePaths
							                                       where b.Checked == true && b != item.PrimaryBackdrop
							                                       select new Uri(ImageUtil.GetLocalImagePath(b.Image))).ToList());
						}
						
						if(item.ImagesPaths != null)
						{
							serie.Posters = new Collection<Uri>((from b in item.ImagesPaths
							                                     where b.Checked == true && b != item.PrimaryImage
							                                     select new Uri(ImageUtil.GetLocalImagePath(b.Image))).ToList());
						}
						
						if(item.BannersPaths != null)
						{
							serie.Graphicals = new Collection<Uri>((from b in item.BannersPaths
							                                        where b.Checked == true && b != item.PrimaryBanner
							                                        select new Uri(ImageUtil.GetLocalImagePath(b.Image))).ToList());
						}
						
						if(item.PrimaryBackdrop != null &&
						   !string.IsNullOrEmpty(item.PrimaryBackdrop.Image))
						{
							serie.Backdrops.Insert(0, new Uri(ImageUtil.GetLocalImagePath(item.PrimaryBackdrop.Image)));
						}
						
						if(item.PrimaryImage != null &&
						   !string.IsNullOrEmpty(item.PrimaryImage.Image))
						{
							serie.Posters.Insert(0, new Uri(ImageUtil.GetLocalImagePath(item.PrimaryImage.Image)));
						}
						
						if(item.PrimaryBanner != null &&
						   !string.IsNullOrEmpty(item.PrimaryBanner.Image))
						{
							serie.Graphicals.Insert(0, new Uri(ImageUtil.GetLocalImagePath(item.PrimaryBanner.Image)));
						}
						
						if(item.Actors != null)
						{
							foreach (var actor in item.Actors) {
								serie.CastMembers.Add(new CastMember
								                      {
								                      	FullName = actor.Name,
								                      	Role = actor.Role,
								                      	Picture = string.IsNullOrEmpty(actor.ImagePath) ? null : new Uri(ImageUtil.GetLocalImagePath(actor.ImagePath)),
								                      	Activity = "Actor"
								                      });
							}
						}

						if(item.Crew != null)
						{
							foreach (var crew in item.Crew) {
								serie.CastMembers.Add(new CastMember
								                      {
								                      	FullName = crew.Name,
								                      	Activity = crew.Activity
								                      });
							}
						}

						AddInSaverManager.Current.SaveSerie(item.Path, serie);
						break;
					case Entity.Season:
						Season season = new Season()
						{
							Number = int.Parse(item.SeasonNumber),
							Images = new Collection<Uri>()
						};
						
						if(item.ImagesPaths != null)
						{
							season.Images = new Collection<Uri>((from i in item.ImagesPaths
							                                     where i.Checked == true
							                                     select new Uri(ImageUtil.GetLocalImagePath(i.Image))).ToList());
						}
						
						AddInSaverManager.Current.SaveSeason(item.Path, season);
						break;
					case Entity.Episode:
						Episode episode = new Episode()
						{
							Directors = new Collection<string>(),
							Writers = new Collection<string>(),
							GuestStars = new Collection<string>(),
							Images = new Collection<Uri>(),
							Name = item.Title,
							Number = string.IsNullOrEmpty(item.EpisodeNumber) ? 0 : int.Parse(item.EpisodeNumber),
							Overview = item.Overview,
							Rating = item.Rating.HasValue ? item.Rating.Value : 0.0F,
							SeasonNumber =string.IsNullOrEmpty(item.SeasonNumber) ? 0 :  int.Parse(item.SeasonNumber),
							Year = item.Year.HasValue ? item.Year.Value : 0,
							FirstAired = item.FirstAired
						};
						
						if(item.Crew != null)
						{
							episode.Directors = new Collection<string>((from c in item.Crew
							                                            where c.Activity.ToLower().Contains("direct")
							                                            select c.Name).ToList());
							
							episode.Writers = new Collection<string>((from c in item.Crew
							                                          where c.Activity.ToLower().Contains("writer")
							                                          select c.Name).ToList());
						}
						
						if(item.Actors != null)
						{
							episode.GuestStars = new Collection<string>((from a in item.Actors
							                                             select a.Name).ToList());
						}
						
						if(item.ImagesPaths != null)
						{
							episode.Images = new Collection<Uri>((from i in item.ImagesPaths
							                                      where i.Checked == true && i != item.PrimaryImage
							                                      select new Uri(ImageUtil.GetLocalImagePath(i.Image))).ToList());
						}
						
						if(item.PrimaryImage != null &&
						   !string.IsNullOrEmpty(item.PrimaryImage.Image))
						{
							episode.Images.Insert(0, new Uri(ImageUtil.GetLocalImagePath(item.PrimaryImage.Image)));
						}
						
						AddInSaverManager.Current.SaveEpisode(item.Path, episode);
						break;
				}
				
				return true;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError("Exception in the ProviderUtil Write in location" + item.Path, ex);
				return false;
			}
		}
	}
}